package com.iwhalecloud.bss.kite.cucc.service.util;

import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.common.util.DecimalCalc;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.domain.inst.repository.SceneInstRepository;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttrValue;
import com.iwhalecloud.bss.kite.manager.inst.KiteInst;
import com.iwhalecloud.bss.kite.service.attr.AttrData;
import com.iwhalecloud.bss.kite.service.scene.attr.OperateInstAttrService;
import com.ztesoft.bss.common.util.SpringUtil;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Description 资费计划套内用量计算
 * @Author deng.gang
 * @Date 2021/9/30 4:06 下午
 */
public class CalculatePkgUsageUtil {

    // 所有需要联动的FIELD_NAME
    private static final String FLOW_PKG_FIELD_NAME = "200004074"; // 流量套包
    private static final String PKG_USAGE_FIELD_NAME = "200004083"; // 套内用量
    private static final String PERIOD_FIELD_NAME = "210005124"; // 期限（年）
    private static final String PKG_PRICE_FIELD_NAME = "200003704"; // 套包价格(元/期限)
    private static final String PROD_TYPE_FIELD_NAME = "200001880"; // 产品类型
    private static Pattern NUMBER_PATTERN = Pattern.compile("[^0-9\\.]");

    public static void calculatePkgUsage(KiteAttr attr, KiteInst inst, AttrData data) {
        if (KiteStringUtils.isEmpty(attr.getValue())) {
            return;
        }
        KiteAttr flowPackageAttr = inst.getAttr(FLOW_PKG_FIELD_NAME); // 流量套包
        KiteAttr pkgUsageAttr = inst.getAttr(PKG_USAGE_FIELD_NAME);  // 套内用量
        KiteAttr periodAttr = inst.getAttr(PERIOD_FIELD_NAME); // 期限（年）
        KiteAttr prodTypeAttr = inst.getAttr(PROD_TYPE_FIELD_NAME); // 产品类型
        // 确保取到的属性值是最新的
        if (FLOW_PKG_FIELD_NAME.equals(attr.getFieldName())) {
            flowPackageAttr = attr;
        }
        if (PKG_USAGE_FIELD_NAME.equals(attr.getFieldName())) {
            pkgUsageAttr = attr;
        }
        if (PERIOD_FIELD_NAME.equals(attr.getFieldName())) {
            periodAttr = attr;
        }
        if (PROD_TYPE_FIELD_NAME.equals(attr.getFieldName())) {
            prodTypeAttr = attr;
        }
        if (Objects.nonNull(flowPackageAttr) && Objects.nonNull(pkgUsageAttr)) {
            String prodType = Optional.ofNullable(prodTypeAttr).map(KiteAttr::getValue).orElse(null);
            List<DcPublic> dcPublicList = DcPublicCache.getByPcode(inst.getSpecId(), prodType, flowPackageAttr.getValue());
            List<KiteAttrValue> attrValues;
            if ("100007196".equals(flowPackageAttr.getValue())) {
                pkgUsageAttr.setAttrId("202106151626"); // 年包套内用量下拉值
                attrValues = SceneInstRepository.getKiteAttrValues(pkgUsageAttr);
            } else {
                pkgUsageAttr.setAttrId("202106151453"); // 月包套内用量下拉值
                attrValues = SceneInstRepository.getKiteAttrValues(pkgUsageAttr);
            }
            // 补充下拉值
            doSupplyAttrValues(attrValues, dcPublicList);
            String periodValue = "1";
            if (KiteListUtils.isNotEmpty(dcPublicList)) {
                if (Objects.nonNull(periodAttr) && KiteStringUtils.equalsAny(periodAttr.getShowType(), KeyConsts.PROD_ATTR_SHOW_TYPE_D, KeyConsts.PROD_ATTR_SHOW_TYPE_M)) {
                    String periodDesc = periodAttr.getValueDesc();
                    DcPublic dcPublic = dcPublicList.stream().filter(config -> KiteStringUtils.equals(config.getCodeb(), periodDesc)).findFirst().orElse(null);
                    if (Objects.nonNull(dcPublic)) {
                        attrValues = attrValues.stream().filter(attrValue -> KiteStringUtils.equals(dcPublic.getCodea(), attrValue.getAttrValue())).collect(Collectors.toList());
                    }
                    periodValue = periodDesc;
                } else {
                    // 不存在期限属性，套包为年包则默认一年
                    if ("100007196".equals(flowPackageAttr.getValue())) {
                        DcPublic dcPublic = dcPublicList.stream().filter(config -> KiteStringUtils.equals(config.getCodeb(), "1")).findFirst().orElse(null);
                        if (Objects.nonNull(dcPublic)) {
                            attrValues = attrValues.stream().filter(attrValue -> KiteStringUtils.equals(dcPublic.getCodea(), attrValue.getAttrValue())).collect(Collectors.toList());
                        }
                    } else {
                        attrValues = attrValues.stream().filter(attrValue -> {
                            if (dcPublicList.stream().anyMatch(dcPublic -> KiteStringUtils.equals(dcPublic.getCodea(), attrValue.getAttrValue()))) {
                                return true;
                            }
                            return false;
                        }).collect(Collectors.toList());
                    }
                }
            }
            if(KiteListUtils.isNotEmpty(attrValues)){
                pkgUsageAttr.setAttrValues(attrValues);
                SpringUtil.getBean(OperateInstAttrService.class).setAttrValue(inst, PKG_USAGE_FIELD_NAME, attrValues.get(0).getAttrValue(), data.getSceneInstId(), null);
            }
            // 流量套包联动展示套包价格
            if(KiteStringUtils.isNotEmpty(pkgUsageAttr.getValue())){
                boolean isCalcByPkg = true; // 是否按套内用量来计算套包价格，默认是
                String price = "";
                if (KiteStringUtils.equals(inst.getSpecId(), "30000017018")) {
                    /**
                     * 物联网标准化连接CAT1
                     * 月包 C1：0.42元/月，C2：1.2元/月，C3：2.4元/月，C4：3.6元/月；
                     * 年包 C1：5元/年，C2：14.4元/年，C3:28.8元/年，C4：43.2元/年；
                     */
                    String flowPkgVal = flowPackageAttr.getValue();
                    DcPublic priceConfig = DcPublicCache.getByPcode("20210930002", prodType, flowPkgVal).stream().findFirst().orElse(null);
                    if (Objects.nonNull(priceConfig)) {
                        price = priceConfig.getCodea();
                        // 如果存在期限（年），则需要根据期限来计算套包价格
                        if (Objects.nonNull(periodAttr) && KiteStringUtils.equalsAny(periodAttr.getShowType(), KeyConsts.PROD_ATTR_SHOW_TYPE_D, KeyConsts.PROD_ATTR_SHOW_TYPE_M)) {
                            String period = periodAttr.getValueDesc();
                            price = doubleTrans(DecimalCalc.mul(price, period));
                        }
                        isCalcByPkg = false;
                    }
                }
                if (isCalcByPkg) {
                    // 年包，因为配置表的数据有些会不一致，所以根据资费计划区分下
                    if (KiteStringUtils.equalsAny(inst.getSpecId(), "30000017020") &&
                        "100007196".equals(flowPackageAttr.getValue())) {
                        price = CalculatePrice(pkgUsageAttr, periodValue);
                    } else {
                        price = DcPublicCache.getCodea("202012180001", pkgUsageAttr.getValue());
                    }

                }
                if(KiteStringUtils.isNotEmpty(price)){
                    SpringUtil.getBean(OperateInstAttrService.class).setAttrValue(inst, PKG_PRICE_FIELD_NAME, price, data.getSceneInstId(), null);
                }
            }
        }
    }

    /**
     * 计算套包价格比如 1080M
     * 1080M/12个月/期限年=每个月的套内用量，从配置中取出每个月的套内用量对应的价格*12*期限年
     * @param pkgUsageAttr
     * @param periodValue
     * @return
     */
    public static String CalculatePrice(KiteAttr pkgUsageAttr, String periodValue) {
        String valueDesc = pkgUsageAttr.getValueDesc();
        if (KiteStringUtils.isEmpty(valueDesc) || (!valueDesc.contains("MB") && !valueDesc.contains("GB") && !valueDesc.contains("TB"))) {
            return "";
        }
        String commonMonth = "12";
        // 不需要针对单位转换，过滤出数字就好
        String unit = valueDesc.substring(valueDesc.length() - 2);
        Double pkgValue = DecimalCalc.div(String.valueOf(DecimalCalc.div(filterNumber(valueDesc), periodValue)), commonMonth); // 得到每个月的套内用量
        StringBuffer sb = new StringBuffer();
        sb.append(doubleTrans(pkgValue)).append(unit);
        DcPublic config = DcPublicCache.get("202012180001").stream().filter(dcPublic -> KiteStringUtils.isEqual(dcPublic.getPname(), sb.toString())).findFirst().orElse(null);
        String monthPrice = Optional.ofNullable(config).map(DcPublic::getCodea).orElse("");
        return KiteStringUtils.isEmpty(monthPrice) ? monthPrice : doubleTrans(DecimalCalc.mul(DecimalCalc.mul(monthPrice, commonMonth), Double.valueOf(periodValue)));
    }

    private static String filterNumber(String value) {
        return NUMBER_PATTERN.matcher(value).replaceAll("").trim();
    }
    /**
     * 补充下拉值
     * @param attrValues
     * @param dcPublicList
     */
    private static void doSupplyAttrValues(List<KiteAttrValue> attrValues, List<DcPublic> dcPublicList) {
        if (KiteListUtils.isEmpty(dcPublicList)) {
            return;
        }
        dcPublicList.stream().filter(dcPublic ->
            !attrValues.stream().anyMatch(attrValue -> KiteStringUtils.equals(dcPublic.getCodea(), attrValue.getAttrValue())))
            .forEach(res -> {
                KiteAttrValue kiteAttrValue = new KiteAttrValue();
                kiteAttrValue.setAttrId(Optional.ofNullable(attrValues.get(0)).map(KiteAttrValue::getAttrId).orElse(""));
                kiteAttrValue.setAttrValue(res.getCodea());
                kiteAttrValue.setAttrValueName(res.getCodec());
                attrValues.add(kiteAttrValue);
            });
    }

    /**
     * Double处理小数点
     * @param d
     * @return
     */
    public static String doubleTrans(double d){
        if(Math.round(d) - d == 0){
            return String.valueOf((long)d);
        }
        return String.valueOf(d);
    }

    /**
     * 比较两个带宽的大小，目前只有 MBPS, GBPS单位
     * @param targetWidth
     * @param sourceWidth
     * @return
     */
    public static boolean compareWidth(String targetWidth, String sourceWidth) {
        boolean result = false;
        String regex = "[^x00-xff]";
        // 存在双字节字符，不比较
        if (Pattern.compile(regex).matcher(targetWidth).matches()) {
            return result;
        }
        float targetNumber = Float.valueOf(targetWidth.replaceAll("[^0-9\\.]", "").trim());
        float sourceNumber = Float.valueOf(sourceWidth.replaceAll("[^0-9\\.]", "").trim());
        String targetUnit = targetWidth.replaceAll("[0-9\\.]", "").trim();
        String sourceUnit = sourceWidth.replaceAll("[0-9\\.]", "").trim();

        if (KiteStringUtils.startsWith(targetUnit, "G")) {
            targetNumber = targetNumber * 1024 * 1024;
        } else if (KiteStringUtils.startsWith(targetUnit, "M")) {
            targetNumber = targetNumber * 1024;
        }

        if (KiteStringUtils.startsWith(sourceUnit, "G")) {
            sourceNumber = sourceNumber * 1024 * 1024;
        } else if (KiteStringUtils.startsWith(sourceUnit, "M")) {
            sourceNumber = sourceNumber * 1024;
        }

        if (targetNumber >= sourceNumber) {
            result = true;
        }
        return result;
    }
}
